
package it.neokree.materialnavigationdrawermodule.elements;

import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.StackLayout;
import ohos.agp.components.Text;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.multimodalinput.event.TouchEvent;

import it.neokree.materialnavigationdrawermodule.ResourceTable;
import it.neokree.materialnavigationdrawermodule.elements.listeners.MaterialSectionListener;
import it.neokree.materialnavigationdrawermodule.util.Utils;
import it.neokree.materialnavigationdrawermodule.view.RoundImage;


/**
 * Navigation Drawer section with Material Design style
 * <p>
 * Created by neokree on 08/11/14.
 */
@SuppressWarnings("unused")
public class MaterialSection<Fraction> implements Component.TouchEventListener, Component.ClickedListener {

    public static final int TARGET_FRAGMENT = 0;
    public static final int TARGET_ACTIVITY = 1;
    public static final int TARGET_LISTENER = 2;

    public static final int ICON_NO_ICON = 0;
    public static final int ICON_24DP = 1;
    public static final int ICON_40DP = 2;

    private int accountPosition; // used only for keep tracking of account section
    private int targetType;
    private Component view;
    private Text text;
    private Text notifications;
    private Image icon;
    private StackLayout ripple;
    private MaterialSectionListener listener;
    private boolean isSelected;
    private boolean hasSectionColor;
    private boolean hasColorDark;
    private boolean realColor;
    private boolean touchable;

    // COLORS
    private int colorPressed;
    private int colorUnpressed;
    private int colorSelected;
    private int sectionColor;
    private int colorDark;
    private int textColor;
    private int notificationColor;

    private int numberNotifications;

    private String title;

    // TARGETS
    private Fraction targetFragment;
    private Intent targetIntent;
    private MaterialSectionListener targetListener;

    public MaterialSection(Context ctx, int iconType, boolean hasRippleSupport, int target) {

        if (rippleAnimationSupport()) {
            // section with ripple effect

            switch (iconType) {
                case ICON_NO_ICON:
                    view = LayoutScatter.getInstance(ctx).parse(ResourceTable.Layout_layout_material_section_ripple, null, false);
                    break;
                case ICON_24DP:
                    view = LayoutScatter.getInstance(ctx).parse(ResourceTable.Layout_layout_material_section_icon_ripple, null, false);

                    icon = (Image) view.findComponentById(ResourceTable.Id_section_icon);
                    break;
                case ICON_40DP:
                    view = LayoutScatter.getInstance(ctx).parse(ResourceTable.Layout_layout_material_section_icon_large_ripple, null, false);

                    icon = (Image) view.findComponentById(ResourceTable.Id_section_icon);
                    break;
            }

            text = (Text) view.findComponentById(ResourceTable.Id_section_text);
            notifications = (Text) view.findComponentById(ResourceTable.Id_section_notification);
            ripple = (StackLayout) view.findComponentById(ResourceTable.Id_section_ripple);

        } else {
            // section with normal background

            switch (iconType) {
                case ICON_NO_ICON:
                    break;
                case ICON_24DP:
                    break;
                case ICON_40DP:
                    break;
            }
        }

        colorPressed = 0x16000000;
        colorUnpressed = 0x00FFFFFF;
        colorSelected = Color.getIntColor("#E4E4E4");
        textColor = 0x000;
        notificationColor = 0x000;

//            // set text color into the view
        if (textColor != 0x000) {
            text.setTextColor(new Color(textColor));
        }
        if (notificationColor != 0x000) {
            notifications.setTextColor(new Color(notificationColor));
        }
//
//            // set background color into the view
        if (!rippleAnimationSupport()) {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(new RgbColor(colorUnpressed));
            view.setBackground(shapeElement);
        }

        if (rippleAnimationSupport()) {
            ripple.setClickedListener(this);
        } else {
            view.setTouchEventListener(this);
        }

        isSelected = false;
        hasSectionColor = false;
        hasColorDark = false;
        touchable = true;
        realColor = false;
        targetType = target;
        numberNotifications = 0;
    }

    // methods for customizations

    public MaterialSection setSectionColor(int color) {
        hasSectionColor = true;
        sectionColor = color;

        return this;
    }

    public MaterialSection setSectionColor(int color, int colorDark) {
        setSectionColor(color);
        hasColorDark = true;
        this.colorDark = colorDark;

        return this;
    }

    /**
     * Set the number of notification for this section
     *
     * @param notifications the number of notification active for this section
     * @return this section
     */
    public MaterialSection setNotifications(int notifications) {
        String textNotification;

        textNotification = String.valueOf(notifications);

        if (notifications < 1) {
            textNotification = "";
        }
        if (notifications > 99) {
            textNotification = "99+";
        }

        this.notifications.setText(textNotification);
        numberNotifications = notifications;

        return this;
    }

    public MaterialSection setNotificationsText(String text) {
        this.notifications.setText(text);
        return this;
    }

    public MaterialSection useRealColor() {
        realColor = true;
        if (icon != null) {
            Utils.setAlpha(icon, 1f);
        }

        return this;
    }

    // internal methods

    // touch event without ripple support
    @Override
    public boolean onTouchEvent(Component v, TouchEvent event) {
        if (touchable) {

            if (event.getAction() == TouchEvent.PRIMARY_POINT_DOWN) {
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(new RgbColor(colorPressed));
                view.setBackground(shapeElement);

                return true;
            }

            if (event.getAction() == TouchEvent.CANCEL) {
                if (isSelected) {
                    ShapeElement shapeElement = new ShapeElement();
                    shapeElement.setRgbColor(new RgbColor(colorSelected));
                    view.setBackground(shapeElement);
                } else {
                    ShapeElement shapeElement = new ShapeElement();
                    shapeElement.setRgbColor(new RgbColor(colorUnpressed));
                    view.setBackground(shapeElement);
                }
                return true;
            }

            if (event.getAction() == TouchEvent.PRIMARY_POINT_UP) {
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(new RgbColor(colorSelected));
                view.setBackground(shapeElement);
                afterClick();
                return true;
            }
        }
        return false;
    }

    //click event with ripple support
    @Override
    public void onClick(Component v) {
        if (touchable) {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(RgbColor.fromArgbInt(colorSelected));
            ripple.setBackground(shapeElement);

            afterClick();
        }
    }

    public void select() {
        isSelected = true;
        if (!rippleAnimationSupport()) {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(RgbColor.fromArgbInt(colorSelected));
            view.setBackground(shapeElement);
        } else {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(RgbColor.fromArgbInt(colorSelected));
            ripple.setBackground(shapeElement);
        }

        if (hasSectionColor) {
            text.setTextColor(new Color(sectionColor));

            if (icon != null && !realColor) {
                Utils.setAlpha(icon, 1f);
            }
        }
    }

    public void unSelect() {
        isSelected = false;
        if (!rippleAnimationSupport()) {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(RgbColor.fromArgbInt(colorUnpressed));
            view.setBackground(shapeElement);
        } else {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(new RgbColor(Color.WHITE.getValue()));
            ripple.setBackground(shapeElement);
        }

        if (hasSectionColor) {
            text.setTextColor(new Color(textColor));

            if (icon != null && !realColor) {
                Utils.setAlpha(icon, 0.54f);
            }
        }
    }

    public boolean isSelected() {
        return isSelected;
    }

    // setter

    public void setAccountPosition(int position) { // used only for keep tracking of account section
        this.accountPosition = position;
    }

    public void setOnClickListener(MaterialSectionListener listener) {
        this.listener = listener;
    }

    public void setTitle(String title) {
        this.title = title;
        this.text.setText(title);
    }

    public void setTitle(Element title) {
        this.icon.setImageElement(title);
    }

    public void setIcon(int icon) {
        if (this.icon instanceof RoundImage) {
            ((RoundImage) this.icon).setPixelMapAndCircle(icon);
        } else {
            this.icon.setPixelMap(icon);
        }

        if (!realColor) {
        }

    }

    public void setIcon(PixelMap icon) {
        if (this.icon instanceof RoundImage) {
            ((RoundImage) this.icon).setPixelMapAndCircle(icon);
        } else {
            this.icon.setPixelMap(icon);
        }

    }

    public void setTarget(Fraction target) {
        this.targetFragment = target;
    }

    public void setTarget(Intent target) {
        this.targetIntent = target;
    }

    public void setTarget(MaterialSectionListener target) {
        this.targetListener = target;
    }

    public void setTypeface(Font typeface) {
        this.text.setFont(typeface);
        this.notifications.setFont(typeface);
    }

    public void setTouchable(boolean isTouchable) {
        touchable = isTouchable;
    }

    public void setPressingColor(int color) {
        colorPressed = color;

        if (rippleAnimationSupport()) {
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setRgbColor(RgbColor.fromArgbInt(colorPressed));
            ripple.setBackground(shapeElement);
        }

    }

    // alias of setColorUnpressed
    public void setBackgroundColor(int color) {
        colorUnpressed = color;

        if (!isSelected()) {
            if (rippleAnimationSupport()) {
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(RgbColor.fromArgbInt(colorUnpressed));
                ripple.setBackground(shapeElement);
            } else {
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(RgbColor.fromArgbInt(colorUnpressed));
                view.setBackground(shapeElement);
            }
        }
    }

    public void setColorSelected(int color) {
        colorSelected = color;

        if (isSelected()) {
            if (rippleAnimationSupport()) {
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(RgbColor.fromArgbInt(colorSelected));
                ripple.setBackground(shapeElement);
            } else {
                ShapeElement shapeElement = new ShapeElement();
                shapeElement.setRgbColor(RgbColor.fromArgbInt(colorSelected));
                view.setBackground(shapeElement);
            }
        }
    }

    // getter

    public Component getView() {
        return view;
    }

    public String getTitle() {
        return title;
    }

    public int getAccountPosition() { // used only for keep tracking of account section
        return accountPosition;
    }

    public int getTarget() {
        return targetType;
    }

    public Fraction getTargetFragment() {
        return targetFragment;
    }

    public Intent getTargetIntent() {
        return targetIntent;
    }

    public MaterialSectionListener getTargetListener() {
        return targetListener;
    }

    public boolean hasSectionColor() {
        return hasSectionColor;
    }

    public boolean hasSectionColorDark() {
        return hasColorDark;
    }

    public int getSectionColor() {
        return sectionColor;
    }

    public int getSectionColorDark() {
        return colorDark;
    }

    public int getNotifications() {
        return numberNotifications;
    }

    public String getNotificationsText() {
        return this.notifications.getText().toString();
    }

    // private methods
    private void afterClick() {
        isSelected = true;

        if (hasSectionColor) {
            text.setTextColor(new Color(sectionColor));

            if (icon != null && !realColor) {
                Utils.setAlpha(icon, 1f);
            }
        }

        if (listener != null) {
            listener.onClick(this);
        }

        // se la sezione ha come target l'activity, dopo che questa viene avviata si deseleziona.
        if (this.getTarget() == TARGET_ACTIVITY) {
            this.unSelect();
        }

        // si fa arrivare il click anche allo sviluppatore
        if (this.getTarget() == TARGET_LISTENER && targetListener != null) {
            this.targetListener.onClick(this);
        }
    }

    private boolean rippleAnimationSupport() {
        return true;
    }


}
